package cn.yangliu.nacos.comm.oauth;

import cn.yangliu.nacos.comm.JsonResult;
import cn.yangliu.nacos.comm.constant.SecurityConstants;
import cn.yangliu.nacos.comm.model.Oauth2InsertModel;
import cn.yangliu.nacos.comm.model.Oauth2Token;
import cn.yangliu.nacos.comm.model.Oauth2UpdateOtherModel;
import cn.yangliu.nacos.comm.model.Oauth2UpdateOtherPasswordModel;
import cn.yangliu.nacos.comm.model.Oauth2UpdatePasswordModel;
import cn.yangliu.nacos.comm.model.Oauth2UpdateSelfModel;
import cn.yangliu.nacos.comm.model.Oauth2UserModel;
import cn.yangliu.nacos.comm.model.Oauth2UserQueryModel;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.cloud.openfeign.SpringQueryMap;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestParam;

/**
 * The type of nacos.
 *
 * @author 问道于盲
 * @date 2019 -12-31
 */
@FeignClient(name = "oauth2", url = "${oauth2.url:}",
        fallback = Oauth2FeignFallback.class)
interface Oauth2FeignClient {

    /**
     * Token json result.
     *
     * @param username     the username
     * @param password     the password
     * @param grantType    authorization_code, password, client_credentials,                  refresh_token
     * @param clientId     the client id
     * @param clientSecret the client secret
     * @param code         the code
     * @param redirectUri  the redirect uri
     * @return json result
     */
    @PostMapping("/oauth/token")
    JsonResult<Oauth2Token> token(@RequestParam("username") String username,
                                  @RequestParam("password") String password,
                                  @RequestParam(value = "grant_type") String grantType,

                                  @RequestParam(value = "client_id") String clientId,
                                  @RequestParam(value = "client_secret") String clientSecret,
                                  @RequestParam(value = "code") String code,
                                  @RequestParam(value = "redirect_uri") String redirectUri);

    /**
     * Register an User
     * <p>
     *
     * @param model model
     * @param token the token
     * @return Oauth2UserModelModel json result
     */
    @PostMapping("/user")
    JsonResult<Oauth2UserModel> insert(@RequestBody Oauth2InsertModel model,
                                  @RequestHeader(SecurityConstants.AUTHORIZATION_KEY) String token);


    /**
     * 更新自己的信息
     *
     * @param model model
     * @param token token
     * @return Oauth2UserModelModel json result
     */
    @PutMapping("/user/updateSelf")
    JsonResult<Oauth2UserModel> updateSelf(@RequestBody Oauth2UpdateSelfModel model,
                                      @RequestHeader(SecurityConstants.AUTHORIZATION_KEY) String token);


    /**
     * 更新自己的信息
     *
     * @param model model
     * @param token token
     * @return Oauth2UserModelModel json result
     */
    @PutMapping("/user/updateOther")
    JsonResult<Oauth2UserModel> updateOther(@RequestBody Oauth2UpdateOtherModel model,
                                       @RequestHeader(SecurityConstants.AUTHORIZATION_KEY) String token);

    /**
     * 更新密码
     *
     * @param model model
     * @param token token
     * @return 修改影响数据条数 integer
     */
    @PutMapping("/user/updateSelfPassword")
    JsonResult<Boolean> updateSelfPassword(@RequestBody Oauth2UpdatePasswordModel model,
                                           @RequestHeader(SecurityConstants.AUTHORIZATION_KEY) String token);

    /**
     * 修改他人密码
     *
     * @param model model
     * @param token the token
     * @return 结果 boolean
     */
    @PutMapping("/user/updateOtherPassword")
    JsonResult<Boolean> updateOtherPassword(@RequestBody Oauth2UpdateOtherPasswordModel model,
                                            @RequestHeader(SecurityConstants.AUTHORIZATION_KEY) String token);

    /**
     * Principal json result.
     *
     * @param token the token
     * @return the json result
     */
    @GetMapping("/user/principal")
    JsonResult<Oauth2UserModel> principal(@RequestHeader(SecurityConstants.AUTHORIZATION_KEY) String token);


    /**
     * Delete json result.
     *
     * @param id    the id
     * @param token the token
     * @return the json result
     */
    @DeleteMapping("/user/delete/{id}")
    JsonResult<Boolean> delete(@PathVariable("id") Long id,
                               @RequestHeader(SecurityConstants.AUTHORIZATION_KEY) String token);


    /**
     * Find json result.
     *
     * @param model the model
     * @param token the token
     * @return the json result
     */
    @GetMapping("/user/findOne")
    JsonResult<Oauth2UserModel> findOne(@SpringQueryMap Oauth2UserQueryModel model,
            @RequestHeader(SecurityConstants.AUTHORIZATION_KEY) String token);

    /**
     * Check exist json result.
     *
     * @param model the model
     * @param token the token
     * @return the json result
     */
    @GetMapping("/user/checkExist")
    JsonResult<Boolean> checkExist(@SpringQueryMap Oauth2UserQueryModel model,
                                   @RequestHeader(SecurityConstants.AUTHORIZATION_KEY) String token);
}
